extern int main();
extern void SystemInit();

void handle_reset();
/*
naked 属性 告诉编译器 不生成 压栈汇编 push 等指令

 0x00-0x03 _start  跳转到reset_func
 0x04-0x08 _vector 中断向量表
 */

// 复位函数
__attribute__((section(".init"), naked)) void _start();
void _start()
{
	handle_reset();
}

/***********************中断向量声明******************************* */
//  声明 中断函数 防止编译器报错
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif

__WEAK void NMI_Handler()
{
	while (1)
		;
} /* NMI */
__WEAK void HardFault_Handler()
{
	while (1)
		;
} /* Hard Fault */

__WEAK void Ecall_M_Mode_Handler() {}	  /* Ecall M Mode */
__WEAK void Ecall_U_Mode_Handler() {}	  /* Ecall U Mode */
__WEAK void Break_Point_Handler() {}	  /* Break Point */
__WEAK void SysTick_Handler() {}		  /* SysTick */
__WEAK void SW_Handler() {}				  /* SW */
__WEAK void WWDG_IRQHandler() {}		  /* Window Watchdog */
__WEAK void PVD_IRQHandler() {}			  /* PVD through EXTI Line detect */
__WEAK void FLASH_IRQHandler() {}		  /* Flash */
__WEAK void EXTI7_0_IRQHandler() {}		  /* EXTI Line 7..0 */
__WEAK void AWU_IRQHandler() {}			  /* Auto Wake up */
__WEAK void DMA1_Channel1_IRQHandler() {} /* DMA1 Channel 1 */
__WEAK void DMA1_Channel2_IRQHandler() {} /* DMA1 Channel 2 */
__WEAK void DMA1_Channel3_IRQHandler() {} /* DMA1 Channel 3 */
__WEAK void DMA1_Channel4_IRQHandler() {} /* DMA1 Channel 4 */
__WEAK void DMA1_Channel5_IRQHandler() {} /* DMA1 Channel 5 */
__WEAK void DMA1_Channel6_IRQHandler() {} /* DMA1 Channel 6 */
__WEAK void DMA1_Channel7_IRQHandler() {} /* DMA1 Channel 7 */
__WEAK void ADC1_IRQHandler() {}		  /* ADC1 */
__WEAK void I2C1_EV_IRQHandler() {}		  /* I2C1 Event */
__WEAK void I2C1_ER_IRQHandler() {}		  /* I2C1 Error */
__WEAK void USART1_IRQHandler() {}		  /* USART1 */
__WEAK void SPI1_IRQHandler() {}		  /* SPI1 */
__WEAK void TIM1_BRK_IRQHandler() {}	  /* TIM1 Break */
__WEAK void TIM1_UP_IRQHandler() {}		  /* TIM1 Update */
__WEAK void TIM1_TRG_COM_IRQHandler() {}  /* TIM1 Trigger and Commutation */
__WEAK void TIM1_CC_IRQHandler() {}		  /* TIM1 Capture Compare */
__WEAK void TIM2_UP_IRQHandler() {}		  /* TIM2 Update */
__WEAK void USART2_IRQHandler() {}		  /* USART2 */
__WEAK void EXTI15_8_IRQHandler() {}	  /* EXTI Line 15..8 */
__WEAK void EXTI25_16_IRQHandler() {}	  /* EXTI Line 25..16 */
__WEAK void USART3_IRQHandler() {}		  /* USART3 */
__WEAK void USART4_IRQHandler() {}		  /* USART4 */
__WEAK void DMA1_Channel8_IRQHandler() {} /* DMA1 Channel8 */
__WEAK void USBFS_IRQHandler() {}		  /* USBFS Break */
__WEAK void USBFSWakeUp_IRQHandler() {}	  /* USBFS Wake up from suspend */
__WEAK void PIOC_IRQHandler() {}		  /* PIOC */
__WEAK void OPA_IRQHandler() {}			  /* OPA */
__WEAK void USBPD_IRQHandler() {}		  /* USBPD */
__WEAK void USBPDWakeUp_IRQHandler() {}	  /* USBPD Wake up */
__WEAK void TIM2_CC_IRQHandler() {}		  /* TIM2 Capture Compare */
__WEAK void TIM2_TRG_COM_IRQHandler() {}  /* TIM2 Trigger and Commutation */
__WEAK void TIM2_BRK_IRQHandler() {}	  /* TIM2 Break */
__WEAK void TIM3_IRQHandler() {}		  /* TIM3 */

/*中断向量表 占用data 区*/

__attribute__((section(".vector"))) const void *_vector_base[] = {

	_start,
	0,
	NMI_Handler,	   /* NMI */
	HardFault_Handler, /* Hard Fault */
	0,
	Ecall_M_Mode_Handler, /* Ecall M Mode */
	0,
	0,
	Ecall_U_Mode_Handler, /* Ecall U Mode */
	Break_Point_Handler,  /* Break Point */
	0,
	0,
	SysTick_Handler, /* SysTick */
	0,
	SW_Handler, /* SW */
	0,
	/* External Interrupts */
	WWDG_IRQHandler /* Window Watchdog */
	,
	PVD_IRQHandler /* PVD through EXTI Line detect */
	,
	FLASH_IRQHandler /* Flash */
	,
	0,
	EXTI7_0_IRQHandler /* EXTI Line 7..0 */
	,
	AWU_IRQHandler /* Auto Wake up */
	,
	DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
	,
	DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
	,
	DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
	,
	DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
	,
	DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */,

	DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
	,
	DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
	,
	ADC1_IRQHandler /* ADC1 */
	,
	I2C1_EV_IRQHandler /* I2C1 Event */
	,
	I2C1_ER_IRQHandler /* I2C1 Error */
	,
	USART1_IRQHandler /* USART1 */
	,
	SPI1_IRQHandler /* SPI1 */
	,
	TIM1_BRK_IRQHandler /* TIM1 Break */
	,
	TIM1_UP_IRQHandler /* TIM1 Update */
	,
	TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
	,
	TIM1_CC_IRQHandler /* TIM1 Capture Compare */
	,
	TIM2_UP_IRQHandler /* TIM2 Update */
	,
	USART2_IRQHandler /* USART2 */
	,
	EXTI15_8_IRQHandler /* EXTI Line 15..8 */
	,
	EXTI25_16_IRQHandler /* EXTI Line 25..16 */
	,
	USART3_IRQHandler /* USART3 */
	,
	USART4_IRQHandler /* USART4 */
	,
	DMA1_Channel8_IRQHandler /* DMA1 Channel8 */
	,
	USBFS_IRQHandler /* USBFS Break */
	,
	USBFSWakeUp_IRQHandler /* USBFS Wake up from suspend */
	,
	PIOC_IRQHandler /* PIOC */
	,
	OPA_IRQHandler /* OPA */
	,
	USBPD_IRQHandler /* USBPD */
	,
	USBPDWakeUp_IRQHandler /* USBPD Wake up */
	,
	TIM2_CC_IRQHandler /* TIM2 Capture Compare */
	,
	TIM2_TRG_COM_IRQHandler /* TIM2 Trigger and Commutation */
	,
	TIM2_BRK_IRQHandler /* TIM2 Break */
	,
	TIM3_IRQHandler /* TIM3 */

};

void handle_reset()
// void _start()
{
	extern unsigned int _data_lma, _sdata, _edata, _sbss, _ebss;

	unsigned int *sdata;		// 0x20000000
	unsigned int *data_atflash; // 0x80000xx

	asm("la sp, _eusrstack");
	// copy data from flash to sram
	sdata = &_sdata;		   // 0x20000000
	data_atflash = &_data_lma; // 0x80000xx
	while (sdata < &_edata)
	{
		*sdata++ = *data_atflash++;
	}

	/*clear bss*/
	sdata = &_sbss;
	while (sdata < &_ebss)
	{
		*sdata++ = 0;
	}

	/* Configure pipelining and instruction prediction */
	asm("li t0, 0x1f");
	asm("csrw 0xbc0, t0");

	/* Enable interrupt nesting and hardware stack */
	asm("li t0, 0x03");
	asm("csrw 0x804, t0");

	/* Configure the interrupt vector table recognition mode and entry address mode */
	asm("la t0, _vector_base");
	asm("ori t0, t0, 3");
	asm("csrw mtvec, t0");

	SystemInit();
	// main();
	asm("la t0, main");
	asm("csrw mepc, t0");
	asm("mret");
}